home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 25 / Cream of the Crop 25.iso / doom / quake_ad.zip / HIPQW.ZIP / SRC / ITEMS.QC < prev    next >
Text File  |  1997-03-13  |  30KB  |  1,408 lines

  1. void() W_SetCurrentAmmo;
  2. /* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD
  3. BE .8 .3 .4 IN COLOR */
  4.  
  5.  
  6. void() SUB_regen =
  7. {
  8.     self.model = self.mdl;        // restore original model
  9.     self.solid = SOLID_TRIGGER;    // allow it to be touched again
  10.     sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);    // play respawn sound
  11.     setorigin (self, self.origin);
  12. };
  13.  
  14.  
  15.  
  16. /*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8)
  17. prints a warning message when spawned
  18. */
  19. void() noclass =
  20. {
  21.     dprint ("noclass spawned at");
  22.     dprint (vtos(self.origin));
  23.     dprint ("\n");
  24.     remove (self);
  25. };
  26.  
  27.  
  28.  
  29. /*
  30. ============
  31. PlaceItem
  32.  
  33. plants the object on the floor
  34. ============
  35. */
  36. void() PlaceItem =
  37. {
  38.     local float    oldz;
  39.  
  40.     self.mdl = self.model;        // so it can be restored on respawn
  41.     self.flags = FL_ITEM;        // make extra wide
  42.     self.solid = SOLID_TRIGGER;
  43.     self.movetype = MOVETYPE_TOSS;    
  44.     self.velocity = '0 0 0';
  45.     self.origin_z = self.origin_z + 6;
  46.     oldz = self.origin_z;
  47.     if (!droptofloor())
  48.     {
  49.         dprint ("Bonus item fell out of level at ");
  50.         dprint (vtos(self.origin));
  51.         dprint ("\n");
  52.         remove(self);
  53.         return;
  54.     }
  55. };
  56.  
  57. /*
  58. ============
  59. StartItem
  60.  
  61. Sets the clipping size and plants the object on the floor
  62. ============
  63. */
  64. void() StartItem =
  65. {
  66.     self.nextthink = time + 0.2;    // items start after other solids
  67.     self.think = PlaceItem;
  68. };
  69.  
  70. /*
  71. =========================================================================
  72.  
  73. HEALTH BOX
  74.  
  75. =========================================================================
  76. */
  77. //
  78. // T_Heal: add health to an entity, limiting health to max_health
  79. // "ignore" will ignore max_health limit
  80. //
  81. float (entity e, float healamount, float ignore) T_Heal =
  82. {
  83.     if (e.health <= 0)
  84.         return 0;
  85.     if ((!ignore) && (e.health >= other.max_health))
  86.         return 0;
  87.     healamount = ceil(healamount);
  88.  
  89.     e.health = e.health + healamount;
  90.     if ((!ignore) && (e.health >= other.max_health))
  91.         e.health = other.max_health;
  92.         
  93.     if (e.health > 250)
  94.         e.health = 250;
  95.     return 1;
  96. };
  97.  
  98. /*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) rotten megahealth
  99. Health box. Normally gives 25 points.
  100. Rotten box heals 5-10 points,
  101. megahealth will add 100 health, then 
  102. rot you down to your maximum health limit, 
  103. one point per second.
  104. */
  105.  
  106. float    H_ROTTEN = 1;
  107. float    H_MEGA = 2;
  108. .float    healamount, healtype;
  109. void() health_touch;
  110. void() item_megahealth_rot;
  111.  
  112. void() item_health =
  113. {    
  114.     self.touch = health_touch;
  115.  
  116.     if (self.spawnflags & H_ROTTEN)
  117.     {
  118.         precache_model("maps/b_bh10.bsp");
  119.  
  120.         precache_sound("items/r_item1.wav");
  121.         setmodel(self, "maps/b_bh10.bsp");
  122.         self.noise = "items/r_item1.wav";
  123.         self.healamount = 15;
  124.         self.healtype = 0;
  125.     }
  126.     else
  127.     if (self.spawnflags & H_MEGA)
  128.     {
  129.         precache_model("maps/b_bh100.bsp");
  130.         precache_sound("items/r_item2.wav");
  131.         setmodel(self, "maps/b_bh100.bsp");
  132.         self.noise = "items/r_item2.wav";
  133.         self.healamount = 100;
  134.         self.healtype = 2;
  135.     }
  136.     else
  137.     {
  138.         precache_model("maps/b_bh25.bsp");
  139.         precache_sound("items/health1.wav");
  140.         setmodel(self, "maps/b_bh25.bsp");
  141.         self.noise = "items/health1.wav";
  142.         self.healamount = 25;
  143.         self.healtype = 1;
  144.     }
  145.     setsize (self, '0 0 0', '32 32 56');
  146.     StartItem ();
  147. };
  148.  
  149.  
  150. void() health_touch =
  151. {
  152.     local    float amount;
  153.     local    string    s;
  154.     
  155.     if (other.classname != "player")
  156.         return;
  157.     
  158.     if (self.healtype == 2) // Megahealth?  Ignore max_health...
  159.     {
  160.         if (other.health >= 250)
  161.             return;
  162.         if (!T_Heal(other, self.healamount, 1))
  163.             return;
  164.     }
  165.     else
  166.     {
  167.         if (!T_Heal(other, self.healamount, 0))
  168.             return;
  169.     }
  170.     
  171.     sprint(other, PRINT_LOW, "You receive ");
  172.     s = ftos(self.healamount);
  173.     sprint(other, PRINT_LOW, s);
  174.     sprint(other, PRINT_LOW, " health\n");
  175.     
  176. // health touch sound
  177.     sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  178.  
  179.     stuffcmd (other, "bf\n");
  180.     
  181.     self.model = string_null;
  182.     self.solid = SOLID_NOT;
  183.  
  184. //hip
  185. //    // Megahealth = rot down the player's super //health
  186. //    if (self.healtype == 2)
  187. //    {
  188. //        other.items = other.items | IT_SUPERHEALTH;
  189. //        self.nextthink = time + 5;
  190. //        self.think = item_megahealth_rot;
  191. //        self.owner = other;
  192. //    }
  193. //    else
  194. //    {
  195.         if (deathmatch != 2)        // deathmatch 2 is the silly old rules
  196.         {
  197.             self.nextthink = time + 20;
  198.             self.think = SUB_regen;
  199.         }
  200. //    }
  201. //hip
  202.     activator = other;
  203.     SUB_UseTargets();                // fire all targets / killtargets
  204. };    
  205.  
  206. void() item_megahealth_rot =
  207. {
  208.     other = self.owner;
  209.     
  210.     if (other.health > other.max_health)
  211.     {
  212.         other.health = other.health - 1;
  213.         self.nextthink = time + 1;
  214.         return;
  215.     }
  216.  
  217. // it is possible for a player to die and respawn between rots, so don't
  218. // just blindly subtract the flag off
  219. //hip
  220. // MED 11/02/96 removed SUPERHEALTH
  221. //   other.items = other.items - (other.items & IT_SUPERHEALTH);
  222. //hip
  223.     
  224.     if (deathmatch == 1)    // deathmatch 2 is silly old rules
  225.     {
  226.         self.nextthink = time + 20;
  227.         self.think = SUB_regen;
  228.     }
  229. };
  230.  
  231. /*
  232. ===============================================================================
  233.  
  234. ARMOR
  235.  
  236. ===============================================================================
  237. */
  238.  
  239. void() armor_touch;
  240.  
  241. void() armor_touch =
  242. {
  243.     local    float    type, value, bit;
  244.     
  245.     if (other.health <= 0)
  246.         return;
  247.     if (other.classname != "player")
  248.         return;
  249.  
  250.     if (self.classname == "item_armor1")
  251.     {
  252.         type = 0.3;
  253.         value = 100;
  254.         bit = IT_ARMOR1;
  255.     }
  256.     if (self.classname == "item_armor2")
  257.     {
  258.         type = 0.6;
  259.         value = 150;
  260.         bit = IT_ARMOR2;
  261.     }
  262.     if (self.classname == "item_armorInv")
  263.     {
  264.         type = 0.8;
  265.         value = 200;
  266.         bit = IT_ARMOR3;
  267.     }
  268.     if (other.armortype*other.armorvalue >= type*value)
  269.         return;
  270.         
  271.     other.armortype = type;
  272.     other.armorvalue = value;
  273.     other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
  274.  
  275.     self.solid = SOLID_NOT;
  276.     self.model = string_null;
  277.     if (deathmatch == 1)
  278.         self.nextthink = time + 20;
  279.     self.think = SUB_regen;
  280.  
  281.     sprint(other, PRINT_LOW, "You got armor\n");
  282. // armor touch sound
  283.     sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM);
  284.     stuffcmd (other, "bf\n");
  285.     
  286.     activator = other;
  287.     SUB_UseTargets();                // fire all targets / killtargets
  288. };
  289.  
  290.  
  291. /*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32)
  292. */
  293.  
  294. void() item_armor1 =
  295. {
  296.     self.touch = armor_touch;
  297.     precache_model ("progs/armor.mdl");
  298.     setmodel (self, "progs/armor.mdl");
  299.     self.skin = 0;
  300.     setsize (self, '-16 -16 0', '16 16 56');
  301.     StartItem ();
  302. };
  303.  
  304. /*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32)
  305. */
  306.  
  307. void() item_armor2 =
  308. {
  309.     self.touch = armor_touch;
  310.     precache_model ("progs/armor.mdl");
  311.     setmodel (self, "progs/armor.mdl");
  312.     self.skin = 1;
  313.     setsize (self, '-16 -16 0', '16 16 56');
  314.     StartItem ();
  315. };
  316.  
  317. /*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32)
  318. */
  319.  
  320. void() item_armorInv =
  321. {
  322.     self.touch = armor_touch;
  323.     precache_model ("progs/armor.mdl");
  324.     setmodel (self, "progs/armor.mdl");
  325.     self.skin = 2;
  326.     setsize (self, '-16 -16 0', '16 16 56');
  327.     StartItem ();
  328. };
  329.  
  330. /*
  331. ===============================================================================
  332.  
  333. WEAPONS
  334.  
  335. ===============================================================================
  336. */
  337.  
  338. void() bound_other_ammo =
  339. {
  340.     if (other.ammo_shells > 100)
  341.         other.ammo_shells = 100;
  342.     if (other.ammo_nails > 200)
  343.         other.ammo_nails = 200;
  344.     if (other.ammo_rockets > 100)
  345.         other.ammo_rockets = 100;        
  346.     if (other.ammo_cells > 100)
  347.         other.ammo_cells = 100;        
  348. };
  349.  
  350. //hip -- modified for new weapons
  351. float(float w) RankForWeapon =
  352. {
  353.     if (w == IT_LIGHTNING)
  354.         return 1;
  355.     if (w == IT_ROCKET_LAUNCHER)
  356.         return 2;
  357.       if (w == IT_LASER_CANNON)
  358.         return 3;
  359.     if (w == IT_MJOLNIR)
  360.           return 9;
  361.     if (w == IT_SUPER_NAILGUN)
  362.         return 4;
  363.     if (w == IT_GRENADE_LAUNCHER)
  364.         return 5;
  365.     if (w == IT_PROXIMITY_GUN)
  366.           return 6;
  367.     if (w == IT_SUPER_SHOTGUN)
  368.         return 7;
  369.     if (w == IT_NAILGUN)
  370.         return 8;
  371.     return 10;
  372. };
  373. //hip
  374.  
  375. /*
  376. =============
  377. Deathmatch_Weapon
  378.  
  379. Deathmatch weapon change rules for picking up a weapon
  380.  
  381. .float        ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
  382. =============
  383. */
  384. void(float old, float new) Deathmatch_Weapon =
  385. {
  386.     local float or, nr;
  387.  
  388. // change self.weapon if desired
  389.     or = RankForWeapon (self.weapon);
  390.     nr = RankForWeapon (new);
  391.     if ( nr < or )
  392.         self.weapon = new;
  393. };
  394.  
  395. /*
  396. =============
  397. weapon_touch
  398. =============
  399. */
  400. float() W_BestWeapon;
  401.  
  402. void() weapon_touch =
  403. {
  404.     local    float    hadammo, best, new, old;
  405.     local    entity    stemp;
  406.     local    float    leave;
  407.  
  408.     if (!(other.flags & FL_CLIENT))
  409.         return;
  410.  
  411. // if the player was using his best weapon, change up to the new one if better        
  412.     stemp = self;
  413.     self = other;
  414.     best = W_BestWeapon();
  415.     self = stemp;
  416.  
  417.     if (deathmatch == 2)
  418.         leave = 1;
  419.     else
  420.         leave = 0;
  421.     
  422.     if (self.classname == "weapon_nailgun")
  423.     {
  424.         if (leave && (other.items & IT_NAILGUN) )
  425.             return;
  426.         hadammo = other.ammo_nails;            
  427.         new = IT_NAILGUN;
  428.         other.ammo_nails = other.ammo_nails + 30;
  429.     }
  430.     else if (self.classname == "weapon_supernailgun")
  431.     {
  432.         if (leave && (other.items & IT_SUPER_NAILGUN) )
  433.             return;
  434.         hadammo = other.ammo_rockets;            
  435.         new = IT_SUPER_NAILGUN;
  436.         other.ammo_nails = other.ammo_nails + 30;
  437.     }
  438.     else if (self.classname == "weapon_supershotgun")
  439.     {
  440.         if (leave && (other.items & IT_SUPER_SHOTGUN) )
  441.             return;
  442.         hadammo = other.ammo_rockets;            
  443.         new = IT_SUPER_SHOTGUN;
  444.         other.ammo_shells = other.ammo_shells + 5;
  445.     }
  446.     else if (self.classname == "weapon_rocketlauncher")
  447.     {
  448.         if (leave && (other.items & IT_ROCKET_LAUNCHER) )
  449.             return;
  450.         hadammo = other.ammo_rockets;            
  451.         new = IT_ROCKET_LAUNCHER;
  452.         other.ammo_rockets = other.ammo_rockets + 5;
  453.     }
  454.     else if (self.classname == "weapon_grenadelauncher")
  455.     {
  456.         if (leave && (other.items & IT_GRENADE_LAUNCHER) )
  457.             return;
  458.         hadammo = other.ammo_rockets;            
  459.         new = IT_GRENADE_LAUNCHER;
  460.         other.ammo_rockets = other.ammo_rockets + 5;
  461.     }
  462.     else if (self.classname == "weapon_lightning")
  463.     {
  464.         if (leave && (other.items & IT_LIGHTNING) )
  465.             return;
  466.         hadammo = other.ammo_rockets;            
  467.         new = IT_LIGHTNING;
  468.         other.ammo_cells = other.ammo_cells + 15;
  469.     }
  470. //hip
  471. //MED
  472.    else if (self.classname == "weapon_laser_gun")
  473.     {
  474.       if (leave && (other.items & IT_LASER_CANNON) )
  475.             return;
  476.         hadammo = other.ammo_rockets;
  477.       new = IT_LASER_CANNON;
  478.       other.ammo_cells = other.ammo_cells + 30;
  479.     }
  480. //MED
  481.    else if (self.classname == "weapon_mjolnir")
  482.     {
  483.       if (leave && (other.items & IT_MJOLNIR) )
  484.             return;
  485.         hadammo = other.ammo_rockets;
  486.       new = IT_MJOLNIR;
  487.       other.ammo_cells = other.ammo_cells + 30;
  488.     }
  489. //MED
  490.    else if (self.classname == "weapon_proximity_gun")
  491.     {
  492.       if (leave && (other.items & IT_PROXIMITY_GUN) )
  493.             return;
  494.         hadammo = other.ammo_rockets;
  495.       new = IT_PROXIMITY_GUN;
  496.       other.ammo_rockets = other.ammo_rockets + 6;
  497.     }
  498. //hip
  499.     else
  500.         objerror ("weapon_touch: unknown classname");
  501.  
  502.     sprint (other, PRINT_LOW, "You got the ");
  503.     sprint (other, PRINT_LOW, self.netname);
  504.     sprint (other, PRINT_LOW, "\n");
  505. // weapon touch sound
  506.     sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  507.     stuffcmd (other, "bf\n");
  508.  
  509.     bound_other_ammo ();
  510.  
  511. // change to the weapon
  512.     old = other.items;
  513.     other.items = other.items | new;
  514.     
  515.     stemp = self;
  516.     self = other;
  517.  
  518.     Deathmatch_Weapon (old, new);
  519.  
  520.     W_SetCurrentAmmo();
  521.  
  522.     self = stemp;
  523.  
  524.     if (leave)
  525.         return;
  526.  
  527. // remove it in single player, or setup for respawning in deathmatch
  528.     self.model = string_null;
  529.     self.solid = SOLID_NOT;
  530.     if (deathmatch == 1)
  531.         self.nextthink = time + 30;
  532.     self.think = SUB_regen;
  533.     
  534.     activator = other;
  535.     SUB_UseTargets();                // fire all targets / killtargets
  536. };
  537.  
  538.  
  539. /*QUAKED weapon_supershotgun (0 .5 .8) (-16 -16 0) (16 16 32)
  540. */
  541.  
  542. void() weapon_supershotgun =
  543. {
  544.     precache_model ("progs/g_shot.mdl");
  545.     setmodel (self, "progs/g_shot.mdl");
  546.     self.weapon = IT_SUPER_SHOTGUN;
  547.     self.netname = "Double-barrelled Shotgun";
  548.     self.touch = weapon_touch;
  549.     setsize (self, '-16 -16 0', '16 16 56');
  550.     StartItem ();
  551. };
  552.  
  553. /*QUAKED weapon_nailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  554. */
  555.  
  556. void() weapon_nailgun =
  557. {
  558.     precache_model ("progs/g_nail.mdl");
  559.     setmodel (self, "progs/g_nail.mdl");
  560.     self.weapon = IT_NAILGUN;
  561.     self.netname = "nailgun";
  562.     self.touch = weapon_touch;
  563.     setsize (self, '-16 -16 0', '16 16 56');
  564.     StartItem ();
  565. };
  566.  
  567. /*QUAKED weapon_supernailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  568. */
  569.  
  570. void() weapon_supernailgun =
  571. {
  572.     precache_model ("progs/g_nail2.mdl");
  573.     setmodel (self, "progs/g_nail2.mdl");
  574.     self.weapon = IT_SUPER_NAILGUN;
  575.     self.netname = "Super Nailgun";
  576.     self.touch = weapon_touch;
  577.     setsize (self, '-16 -16 0', '16 16 56');
  578.     StartItem ();
  579. };
  580.  
  581. /*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  582. */
  583.  
  584. void() weapon_grenadelauncher =
  585. {
  586.     precache_model ("progs/g_rock.mdl");
  587.     setmodel (self, "progs/g_rock.mdl");
  588.     self.weapon = 3;
  589.     self.netname = "Grenade Launcher";
  590.     self.touch = weapon_touch;
  591.     setsize (self, '-16 -16 0', '16 16 56');
  592.     StartItem ();
  593. };
  594.  
  595. /*QUAKED weapon_rocketlauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  596. */
  597.  
  598. void() weapon_rocketlauncher =
  599. {
  600.     precache_model ("progs/g_rock2.mdl");
  601.     setmodel (self, "progs/g_rock2.mdl");
  602.     self.weapon = 3;
  603.     self.netname = "Rocket Launcher";
  604.     self.touch = weapon_touch;
  605.     setsize (self, '-16 -16 0', '16 16 56');
  606.     StartItem ();
  607. };
  608.  
  609.  
  610. /*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32)
  611. */
  612.  
  613. void() weapon_lightning =
  614. {
  615.     precache_model ("progs/g_light.mdl");
  616.     setmodel (self, "progs/g_light.mdl");
  617.     self.weapon = 3;
  618.     self.netname = "Thunderbolt";
  619.     self.touch = weapon_touch;
  620.     setsize (self, '-16 -16 0', '16 16 56');
  621.     StartItem ();
  622. };
  623.  
  624.  
  625. /*
  626. ===============================================================================
  627.  
  628. AMMO
  629.  
  630. ===============================================================================
  631. */
  632.  
  633. void() ammo_touch =
  634. {
  635. local entity    stemp;
  636. local float        best;
  637.  
  638.     if (other.classname != "player")
  639.         return;
  640.     if (other.health <= 0)
  641.         return;
  642.  
  643. // if the player was using his best weapon, change up to the new one if better        
  644.     stemp = self;
  645.     self = other;
  646.     best = W_BestWeapon();
  647.     self = stemp;
  648.  
  649.  
  650. // shotgun
  651.     if (self.weapon == 1)
  652.     {
  653.         if (other.ammo_shells >= 100)
  654.             return;
  655.         other.ammo_shells = other.ammo_shells + self.aflag;
  656.     }
  657.  
  658. // spikes
  659.     if (self.weapon == 2)
  660.     {
  661.         if (other.ammo_nails >= 200)
  662.             return;
  663.         other.ammo_nails = other.ammo_nails + self.aflag;
  664.     }
  665.  
  666. //    rockets
  667.     if (self.weapon == 3)
  668.     {
  669.         if (other.ammo_rockets >= 100)
  670.             return;
  671.         other.ammo_rockets = other.ammo_rockets + self.aflag;
  672.     }
  673.  
  674. //    cells
  675.     if (self.weapon == 4)
  676.     {
  677.         if (other.ammo_cells >= 100)
  678.             return;
  679.         other.ammo_cells = other.ammo_cells + self.aflag;
  680.     }
  681.  
  682.     bound_other_ammo ();
  683.     
  684.     sprint (other, PRINT_LOW, "You got the ");
  685.     sprint (other, PRINT_LOW, self.netname);
  686.     sprint (other, PRINT_LOW, "\n");
  687. // ammo touch sound
  688.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  689.     stuffcmd (other, "bf\n");
  690.  
  691. // change to a better weapon if appropriate
  692.  
  693.     if ( other.weapon == best )
  694.     {
  695.         stemp = self;
  696.         self = other;
  697.         self.weapon = W_BestWeapon();
  698.         W_SetCurrentAmmo ();
  699.         self = stemp;
  700.     }
  701.  
  702. // if changed current ammo, update it
  703.     stemp = self;
  704.     self = other;
  705.     W_SetCurrentAmmo();
  706.     self = stemp;
  707.  
  708. // remove it in single player, or setup for respawning in deathmatch
  709.     self.model = string_null;
  710.     self.solid = SOLID_NOT;
  711.     if (deathmatch == 1)
  712.         self.nextthink = time + 30;
  713.     
  714.     self.think = SUB_regen;
  715.  
  716.     activator = other;
  717.     SUB_UseTargets();                // fire all targets / killtargets
  718. };
  719.  
  720.  
  721.  
  722.  
  723. float WEAPON_BIG2 = 1;
  724.  
  725. /*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) big
  726. */
  727.  
  728. void() item_shells =
  729. {
  730.     self.touch = ammo_touch;
  731.  
  732.     if (self.spawnflags & WEAPON_BIG2)
  733.     {
  734.         precache_model ("maps/b_shell1.bsp");
  735.         setmodel (self, "maps/b_shell1.bsp");
  736.         self.aflag = 40;
  737.     }
  738.     else
  739.     {
  740.         precache_model ("maps/b_shell0.bsp");
  741.         setmodel (self, "maps/b_shell0.bsp");
  742.         self.aflag = 20;
  743.     }
  744.     self.weapon = 1;
  745.     self.netname = "shells";
  746.     setsize (self, '0 0 0', '32 32 56');
  747.     StartItem ();
  748. };
  749.  
  750. /*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) big
  751. */
  752.  
  753. void() item_spikes =
  754. {
  755.     self.touch = ammo_touch;
  756.  
  757.     if (self.spawnflags & WEAPON_BIG2)
  758.     {
  759.         precache_model ("maps/b_nail1.bsp");
  760.         setmodel (self, "maps/b_nail1.bsp");
  761.         self.aflag = 50;
  762.     }
  763.     else
  764.     {
  765.         precache_model ("maps/b_nail0.bsp");
  766.         setmodel (self, "maps/b_nail0.bsp");
  767.         self.aflag = 25;
  768.     }
  769.     self.weapon = 2;
  770.     self.netname = "nails";
  771.     setsize (self, '0 0 0', '32 32 56');
  772.     StartItem ();
  773. };
  774.  
  775. /*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) big
  776. */
  777.  
  778. void() item_rockets =
  779. {
  780.     self.touch = ammo_touch;
  781.  
  782.     if (self.spawnflags & WEAPON_BIG2)
  783.     {
  784.         precache_model ("maps/b_rock1.bsp");
  785.         setmodel (self, "maps/b_rock1.bsp");
  786.         self.aflag = 10;
  787.     }
  788.     else
  789.     {
  790.         precache_model ("maps/b_rock0.bsp");
  791.         setmodel (self, "maps/b_rock0.bsp");
  792.         self.aflag = 5;
  793.     }
  794.     self.weapon = 3;
  795.     self.netname = "rockets";
  796.     setsize (self, '0 0 0', '32 32 56');
  797.     StartItem ();
  798. };
  799.  
  800.  
  801. /*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) big
  802. */
  803.  
  804. void() item_cells =
  805. {
  806.     self.touch = ammo_touch;
  807.  
  808.     if (self.spawnflags & WEAPON_BIG2)
  809.     {
  810.         precache_model ("maps/b_batt1.bsp");
  811.         setmodel (self, "maps/b_batt1.bsp");
  812.         self.aflag = 12;
  813.     }
  814.     else
  815.     {
  816.         precache_model ("maps/b_batt0.bsp");
  817.         setmodel (self, "maps/b_batt0.bsp");
  818.         self.aflag = 6;
  819.     }
  820.     self.weapon = 4;
  821.     self.netname = "cells";
  822.     setsize (self, '0 0 0', '32 32 56');
  823.     StartItem ();
  824. };
  825.  
  826.  
  827. /*QUAKED item_weapon (0 .5 .8) (0 0 0) (32 32 32) shotgun rocket spikes big
  828. DO NOT USE THIS!!!! IT WILL BE REMOVED!
  829. */
  830.  
  831. float WEAPON_SHOTGUN = 1;
  832. float WEAPON_ROCKET = 2;
  833. float WEAPON_SPIKES = 4;
  834. float WEAPON_BIG = 8;
  835. void() item_weapon =
  836. {
  837.     self.touch = ammo_touch;
  838.  
  839.     if (self.spawnflags & WEAPON_SHOTGUN)
  840.     {
  841.         if (self.spawnflags & WEAPON_BIG)
  842.         {
  843.             precache_model ("maps/b_shell1.bsp");
  844.             setmodel (self, "maps/b_shell1.bsp");
  845.             self.aflag = 40;
  846.         }
  847.         else
  848.         {
  849.             precache_model ("maps/b_shell0.bsp");
  850.             setmodel (self, "maps/b_shell0.bsp");
  851.             self.aflag = 20;
  852.         }
  853.         self.weapon = 1;
  854.         self.netname = "shells";
  855.     }
  856.  
  857.     if (self.spawnflags & WEAPON_SPIKES)
  858.     {
  859.         if (self.spawnflags & WEAPON_BIG)
  860.         {
  861.             precache_model ("maps/b_nail1.bsp");
  862.             setmodel (self, "maps/b_nail1.bsp");
  863.             self.aflag = 40;
  864.         }
  865.         else
  866.         {
  867.             precache_model ("maps/b_nail0.bsp");
  868.             setmodel (self, "maps/b_nail0.bsp");
  869.             self.aflag = 20;
  870.         }
  871.         self.weapon = 2;
  872.         self.netname = "spikes";
  873.     }
  874.  
  875.     if (self.spawnflags & WEAPON_ROCKET)
  876.     {
  877.         if (self.spawnflags & WEAPON_BIG)
  878.         {
  879.             precache_model ("maps/b_rock1.bsp");
  880.             setmodel (self, "maps/b_rock1.bsp");
  881.             self.aflag = 10;
  882.         }
  883.         else
  884.         {
  885.             precache_model ("maps/b_rock0.bsp");
  886.             setmodel (self, "maps/b_rock0.bsp");
  887.             self.aflag = 5;
  888.         }
  889.         self.weapon = 3;
  890.         self.netname = "rockets";
  891.     }
  892.     
  893.     setsize (self, '0 0 0', '32 32 56');
  894.     StartItem ();
  895. };
  896.  
  897.  
  898. /*
  899. ===============================================================================
  900.  
  901. KEYS
  902.  
  903. ===============================================================================
  904. */
  905.  
  906. void() key_touch =
  907. {
  908. local entity    stemp;
  909. local float        best;
  910.  
  911.     if (other.classname != "player")
  912.         return;
  913.     if (other.health <= 0)
  914.         return;
  915.     if (other.items & self.items)
  916.         return;
  917.  
  918.     sprint (other, PRINT_LOW, "You got the ");
  919.     sprint (other, PRINT_LOW, self.netname);
  920.     sprint (other,PRINT_LOW, "\n");
  921.  
  922.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  923.     stuffcmd (other, "bf\n");
  924.     other.items = other.items | self.items;
  925.  
  926.     self.solid = SOLID_NOT;
  927.     self.model = string_null;
  928.  
  929.     activator = other;
  930.     SUB_UseTargets();                // fire all targets / killtargets
  931. };
  932.  
  933.  
  934. void() key_setsounds =
  935. {
  936.     if (world.worldtype == 0)
  937.     {
  938.         precache_sound ("misc/medkey.wav");
  939.         self.noise = "misc/medkey.wav";
  940.     }
  941.     if (world.worldtype == 1)
  942.     {
  943.         precache_sound ("misc/runekey.wav");
  944.         self.noise = "misc/runekey.wav";
  945.     }
  946.     if (world.worldtype == 2)
  947.     {
  948.         precache_sound2 ("misc/basekey.wav");
  949.         self.noise = "misc/basekey.wav";
  950.     }
  951. };
  952.  
  953. /*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32)
  954. SILVER key
  955. In order for keys to work
  956. you MUST set your maps
  957. worldtype to one of the
  958. following:
  959. 0: medieval
  960. 1: metal
  961. 2: base
  962. */
  963.  
  964. void() item_key1 =
  965. {
  966.     if (world.worldtype == 0)
  967.     {
  968.         precache_model ("progs/w_s_key.mdl");
  969.         setmodel (self, "progs/w_s_key.mdl");
  970.         self.netname = "silver key";
  971.     }
  972.     else if (world.worldtype == 1)
  973.     {
  974.         precache_model ("progs/m_s_key.mdl");
  975.         setmodel (self, "progs/m_s_key.mdl");
  976.         self.netname = "silver runekey";
  977.     }
  978.     else if (world.worldtype == 2)
  979.     {
  980.         precache_model2 ("progs/b_s_key.mdl");
  981.         setmodel (self, "progs/b_s_key.mdl");
  982.         self.netname = "silver keycard";
  983.     }
  984.     key_setsounds();
  985.     self.touch = key_touch;
  986.     self.items = IT_KEY1;
  987.     setsize (self, '-16 -16 -24', '16 16 32');
  988.     StartItem ();
  989. };
  990.  
  991. /*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32)
  992. GOLD key
  993. In order for keys to work
  994. you MUST set your maps
  995. worldtype to one of the
  996. following:
  997. 0: medieval
  998. 1: metal
  999. 2: base
  1000. */
  1001.  
  1002. void() item_key2 =
  1003. {
  1004.     if (world.worldtype == 0)
  1005.     {
  1006.         precache_model ("progs/w_g_key.mdl");
  1007.         setmodel (self, "progs/w_g_key.mdl");
  1008.         self.netname = "gold key";
  1009.     }
  1010.     if (world.worldtype == 1)
  1011.     {
  1012.         precache_model ("progs/m_g_key.mdl");
  1013.         setmodel (self, "progs/m_g_key.mdl");
  1014.         self.netname = "gold runekey";
  1015.     }
  1016.     if (world.worldtype == 2)
  1017.     {
  1018.         precache_model2 ("progs/b_g_key.mdl");
  1019.         setmodel (self, "progs/b_g_key.mdl");
  1020.         self.netname = "gold keycard";
  1021.     }
  1022.     key_setsounds();
  1023.     self.touch = key_touch;
  1024.     self.items = IT_KEY2;
  1025.     setsize (self, '-16 -16 -24', '16 16 32');
  1026.     StartItem ();
  1027. };
  1028.  
  1029.  
  1030.  
  1031. /*
  1032. ===============================================================================
  1033.  
  1034. END OF LEVEL RUNES
  1035.  
  1036. ===============================================================================
  1037. */
  1038.  
  1039. void() sigil_touch =
  1040. {
  1041. local entity    stemp;
  1042. local float        best;
  1043.  
  1044.     if (other.classname != "player")
  1045.         return;
  1046.     if (other.health <= 0)
  1047.         return;
  1048.  
  1049.     centerprint (other, "You got the rune!");
  1050.  
  1051.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  1052.     stuffcmd (other, "bf\n");
  1053.     self.solid = SOLID_NOT;
  1054.     self.model = string_null;
  1055.     serverflags = serverflags | (self.spawnflags & 15);
  1056.     self.classname = "";        // so rune doors won't find it
  1057.     
  1058.     activator = other;
  1059.     SUB_UseTargets();                // fire all targets / killtargets
  1060. };
  1061.  
  1062.  
  1063. /*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4
  1064. End of level sigil, pick up to end episode and return to jrstart.
  1065. */
  1066.  
  1067. void() item_sigil =
  1068. {
  1069.     if (!self.spawnflags)
  1070.         objerror ("no spawnflags");
  1071.  
  1072.     precache_sound ("misc/runekey.wav");
  1073.     self.noise = "misc/runekey.wav";
  1074.  
  1075.     if (self.spawnflags & 1)
  1076.     {
  1077.         precache_model ("progs/end1.mdl");
  1078.         setmodel (self, "progs/end1.mdl");
  1079.     }
  1080.     if (self.spawnflags & 2)
  1081.     {
  1082.         precache_model2 ("progs/end2.mdl");
  1083.         setmodel (self, "progs/end2.mdl");
  1084.     }
  1085.     if (self.spawnflags & 4)
  1086.     {
  1087.         precache_model2 ("progs/end3.mdl");
  1088.         setmodel (self, "progs/end3.mdl");
  1089.     }
  1090.     if (self.spawnflags & 8)
  1091.     {
  1092.         precache_model2 ("progs/end4.mdl");
  1093.         setmodel (self, "progs/end4.mdl");
  1094.     }
  1095.     
  1096.     self.touch = sigil_touch;
  1097.     setsize (self, '-16 -16 -24', '16 16 32');
  1098.     StartItem ();
  1099. };
  1100.  
  1101. /*
  1102. ===============================================================================
  1103.  
  1104. POWERUPS
  1105.  
  1106. ===============================================================================
  1107. */
  1108.  
  1109. void() powerup_touch;
  1110.  
  1111.  
  1112. void() powerup_touch =
  1113. {
  1114. local entity    stemp;
  1115. local float        best;
  1116.  
  1117.     if (other.classname != "player")
  1118.         return;
  1119.     if (other.health <= 0)
  1120.         return;
  1121.  
  1122.     sprint (other, PRINT_LOW, "You got the ");
  1123.     sprint (other,PRINT_LOW,  self.netname);
  1124.     sprint (other,PRINT_LOW, "\n");
  1125.  
  1126.     self.mdl = self.model;
  1127.     
  1128.     if ((self.classname == "item_artifact_invulnerability") ||
  1129.         (self.classname == "item_artifact_invisibility"))
  1130.         self.nextthink = time + 60*5;
  1131.     else
  1132.         self.nextthink = time + 60;
  1133.     
  1134.     self.think = SUB_regen;
  1135.  
  1136.     sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
  1137.     stuffcmd (other, "bf\n");
  1138.     self.solid = SOLID_NOT;
  1139.     other.items = other.items | self.items;
  1140.     self.model = string_null;
  1141.  
  1142. // do the apropriate action
  1143.     if (self.classname == "item_artifact_envirosuit")
  1144.     {
  1145.         other.rad_time = 1;
  1146.         other.radsuit_finished = time + 30;
  1147.     }
  1148.     
  1149.     if (self.classname == "item_artifact_invulnerability")
  1150.     {
  1151.         other.invincible_time = 1;
  1152.         other.invincible_finished = time + 30;
  1153.     }
  1154.     
  1155.     if (self.classname == "item_artifact_invisibility")
  1156.     {
  1157.         other.invisible_time = 1;
  1158.         other.invisible_finished = time + 30;
  1159.     }
  1160.  
  1161.     if (self.classname == "item_artifact_super_damage")
  1162.     {
  1163.         other.super_time = 1;
  1164.         other.super_damage_finished = time + 30;
  1165.     }    
  1166.  
  1167.     activator = other;
  1168.     SUB_UseTargets();                // fire all targets / killtargets
  1169. };
  1170.  
  1171.  
  1172.  
  1173. /*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32)
  1174. Player is invulnerable for 30 seconds
  1175. */
  1176. void() item_artifact_invulnerability =
  1177. {
  1178.     self.touch = powerup_touch;
  1179.  
  1180.     precache_model ("progs/invulner.mdl");
  1181.     precache_sound ("items/protect.wav");
  1182.     precache_sound ("items/protect2.wav");
  1183.     precache_sound ("items/protect3.wav");
  1184.     self.noise = "items/protect.wav";
  1185.     setmodel (self, "progs/invulner.mdl");
  1186.     self.netname = "Pentagram of Protection";
  1187.     self.items = IT_INVULNERABILITY;
  1188.     setsize (self, '-16 -16 -24', '16 16 32');
  1189.     StartItem ();
  1190. };
  1191.  
  1192. /*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32)
  1193. Player takes no damage from water or slime for 30 seconds
  1194. */
  1195. void() item_artifact_envirosuit =
  1196. {
  1197.     self.touch = powerup_touch;
  1198.  
  1199.     precache_model ("progs/suit.mdl");
  1200.     precache_sound ("items/suit.wav");
  1201.     precache_sound ("items/suit2.wav");
  1202.     self.noise = "items/suit.wav";
  1203.     setmodel (self, "progs/suit.mdl");
  1204.     self.netname = "Biosuit";
  1205.     self.items = IT_SUIT;
  1206.     setsize (self, '-16 -16 -24', '16 16 32');
  1207.     StartItem ();
  1208. };
  1209.  
  1210.  
  1211. /*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32)
  1212. Player is invisible for 30 seconds
  1213. */
  1214. void() item_artifact_invisibility =
  1215. {
  1216.     self.touch = powerup_touch;
  1217.  
  1218.     precache_model ("progs/invisibl.mdl");
  1219.     precache_sound ("items/inv1.wav");
  1220.     precache_sound ("items/inv2.wav");
  1221.     precache_sound ("items/inv3.wav");
  1222.     self.noise = "items/inv1.wav";
  1223.     setmodel (self, "progs/invisibl.mdl");
  1224.     self.netname = "Ring of Shadows";
  1225.     self.items = IT_INVISIBILITY;
  1226.     setsize (self, '-16 -16 -24', '16 16 32');
  1227.     StartItem ();
  1228. };
  1229.  
  1230.  
  1231. /*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32)
  1232. The next attack from the player will do 4x damage
  1233. */
  1234. void() item_artifact_super_damage =
  1235. {
  1236.     self.touch = powerup_touch;
  1237.  
  1238.     precache_model ("progs/quaddama.mdl");
  1239.     precache_sound ("items/damage.wav");
  1240.     precache_sound ("items/damage2.wav");
  1241.     precache_sound ("items/damage3.wav");
  1242.     self.noise = "items/damage.wav";
  1243.     setmodel (self, "progs/quaddama.mdl");
  1244.     self.netname = "Quad Damage";
  1245.     self.items = IT_QUAD;
  1246.     setsize (self, '-16 -16 -24', '16 16 32');
  1247.     StartItem ();
  1248. };
  1249.  
  1250.  
  1251.  
  1252. /*
  1253. ===============================================================================
  1254.  
  1255. PLAYER BACKPACKS
  1256.  
  1257. ===============================================================================
  1258. */
  1259.  
  1260. void() BackpackTouch =
  1261. {
  1262.     local string    s;
  1263.     local    float    best, old, new;
  1264.     local        entity    stemp;
  1265.     local    float    acount;
  1266.     
  1267.     if (other.classname != "player")
  1268.         return;
  1269.     if (other.health <= 0)
  1270.         return;
  1271.         
  1272.     acount = 0;
  1273.      sprint (other, PRINT_LOW, "You get ");
  1274.  
  1275.      if (self.items)
  1276.          if ((other.items & self.items) == 0)
  1277.          {
  1278.              acount = 1;
  1279.              sprint (other, PRINT_LOW, "the ");
  1280.              sprint (other, PRINT_LOW, self.netname);
  1281.          }
  1282.  
  1283. // if the player was using his best weapon, change up to the new one if better        
  1284.     stemp = self;
  1285.     self = other;
  1286.     best = W_BestWeapon();
  1287.     self = stemp;
  1288.  
  1289. // change weapons
  1290.     other.ammo_shells = other.ammo_shells + self.ammo_shells;
  1291.     other.ammo_nails = other.ammo_nails + self.ammo_nails;
  1292.     other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
  1293.     other.ammo_cells = other.ammo_cells + self.ammo_cells;
  1294.  
  1295.     new = self.items;
  1296.     if (!new)
  1297.         new = other.weapon;
  1298.     old = other.items;
  1299.     other.items = other.items | self.items;
  1300.     
  1301.     bound_other_ammo ();
  1302.  
  1303.     if (self.ammo_shells)
  1304.     {
  1305.         if (acount)
  1306.             sprint(other, PRINT_LOW, ", ");
  1307.         acount = 1;
  1308.         s = ftos(self.ammo_shells);
  1309.         sprint (other, PRINT_LOW, s);
  1310.         sprint (other, PRINT_LOW, " shells");
  1311.     }
  1312.     if (self.ammo_nails)
  1313.     {
  1314.         if (acount)
  1315.             sprint(other, PRINT_LOW, ", ");
  1316.         acount = 1;
  1317.         s = ftos(self.ammo_nails);
  1318.         sprint (other, PRINT_LOW, s);
  1319.         sprint (other, PRINT_LOW, " nails");
  1320.     }
  1321.     if (self.ammo_rockets)
  1322.     {
  1323.         if (acount)
  1324.             sprint(other, PRINT_LOW, ", ");
  1325.         acount = 1;
  1326.         s = ftos(self.ammo_rockets);
  1327.         sprint (other, PRINT_LOW, s);
  1328.         sprint (other, PRINT_LOW, " rockets");
  1329.     }
  1330.     if (self.ammo_cells)
  1331.     {
  1332.         if (acount)
  1333.             sprint(other, PRINT_LOW, ", ");
  1334.         acount = 1;
  1335.         s = ftos(self.ammo_cells);
  1336.         sprint (other, PRINT_LOW, s);
  1337.         sprint (other,PRINT_LOW, " cells");
  1338.     }
  1339.     
  1340.     sprint (other, PRINT_LOW, "\n");
  1341. // backpack touch sound
  1342.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  1343.     stuffcmd (other, "bf\n");
  1344.  
  1345.     remove(self);
  1346.     self = other;
  1347.     
  1348. // change to the weapon
  1349.     Deathmatch_Weapon (old, new);
  1350.  
  1351.     W_SetCurrentAmmo ();
  1352. };
  1353.  
  1354. /*
  1355. ===============
  1356. DropBackpack
  1357. ===============
  1358. */
  1359. void() DropBackpack =
  1360. {
  1361.     local entity    item;
  1362.  
  1363.     if (!(self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells))
  1364.         return;    // nothing in it
  1365.  
  1366.     item = spawn();
  1367.     item.origin = self.origin - '0 0 24';
  1368.     
  1369.     item.items = self.weapon;
  1370.     if (item.items == IT_AXE)
  1371.          item.netname = "Axe";
  1372.      else if (item.items == IT_SHOTGUN)
  1373.          item.netname = "Shotgun";
  1374.      else if (item.items == IT_SUPER_SHOTGUN)
  1375.          item.netname = "Double-barrelled Shotgun";
  1376.      else if (item.items == IT_NAILGUN)
  1377.          item.netname = "Nailgun";
  1378.      else if (item.items == IT_SUPER_NAILGUN)
  1379.          item.netname = "Super Nailgun";
  1380.      else if (item.items == IT_GRENADE_LAUNCHER)
  1381.          item.netname = "Grenade Launcher";
  1382.      else if (item.items == IT_ROCKET_LAUNCHER)
  1383.          item.netname = "Rocket Launcher";
  1384.      else if (item.items == IT_LIGHTNING)
  1385.          item.netname = "Thunderbolt";
  1386.      else
  1387.          item.netname = "";
  1388.  
  1389.     item.ammo_shells = self.ammo_shells;
  1390.     item.ammo_nails = self.ammo_nails;
  1391.     item.ammo_rockets = self.ammo_rockets;
  1392.     item.ammo_cells = self.ammo_cells;
  1393.  
  1394.     item.velocity_z = 300;
  1395.     item.velocity_x = -100 + (random() * 200);
  1396.     item.velocity_y = -100 + (random() * 200);
  1397.     
  1398.     item.flags = FL_ITEM;
  1399.     item.solid = SOLID_TRIGGER;
  1400.     item.movetype = MOVETYPE_TOSS;
  1401.     setmodel (item, "progs/backpack.mdl");
  1402.     setsize (item, '-16 -16 0', '16 16 56');
  1403.     item.touch = BackpackTouch;
  1404.     
  1405.     item.nextthink = time + 120;    // remove after 2 minutes
  1406.     item.think = SUB_Remove;
  1407. };
  1408.